package com.caipiao.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Locale;

/**
 * 数字处理工具类
 * 提供常用的数字处理方法
 */
public class NumberUtils {

    /**
     * 默认除法运算精度
     */
    private static final int DEFAULT_DIV_SCALE = 10;

    /**
     * 判断字符串是否为数字（整数或小数）
     *
     * @param str 待判断的字符串
     * @return 如果是数字返回true，否则返回false
     */
    public static boolean isNumber(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        try {
            Double.parseDouble(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 判断字符串是否为整数
     *
     * @param str 待判断的字符串
     * @return 如果是整数返回true，否则返回false
     */
    public static boolean isInteger(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        try {
            Integer.parseInt(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 判断字符串是否为长整数
     *
     * @param str 待判断的字符串
     * @return 如果是长整数返回true，否则返回false
     */
    public static boolean isLong(String str) {
        if (str == null || str.length() == 0) {
            return false;
        }
        try {
            Long.parseLong(str);
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    /**
     * 将字符串转换为Integer，如果转换失败返回默认值
     *
     * @param str          字符串
     * @param defaultValue 默认值
     * @return 转换后的Integer或默认值
     */
    public static Integer toInteger(String str, Integer defaultValue) {
        if (str == null) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(str);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 将字符串转换为Integer，如果转换失败返回null
     *
     * @param str 字符串
     * @return 转换后的Integer或null
     */
    public static Integer toInteger(String str) {
        return toInteger(str, null);
    }

    /**
     * 将字符串转换为Long，如果转换失败返回默认值
     *
     * @param str          字符串
     * @param defaultValue 默认值
     * @return 转换后的Long或默认值
     */
    public static Long toLong(String str, Long defaultValue) {
        if (str == null) {
            return defaultValue;
        }
        try {
            return Long.parseLong(str);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 将字符串转换为Long，如果转换失败返回null
     *
     * @param str 字符串
     * @return 转换后的Long或null
     */
    public static Long toLong(String str) {
        return toLong(str, null);
    }

    /**
     * 将字符串转换为Double，如果转换失败返回默认值
     *
     * @param str          字符串
     * @param defaultValue 默认值
     * @return 转换后的Double或默认值
     */
    public static Double toDouble(String str, Double defaultValue) {
        if (str == null) {
            return defaultValue;
        }
        try {
            return Double.parseDouble(str);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    /**
     * 将字符串转换为Double，如果转换失败返回null
     *
     * @param str 字符串
     * @return 转换后的Double或null
     */
    public static Double toDouble(String str) {
        return toDouble(str, null);
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.add(b2).doubleValue();
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double subtract(double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.subtract(b2).doubleValue();
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double multiply(double v1, double v2) {
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.multiply(b2).doubleValue();
    }

    /**
     * 提供精确的除法运算，默认精度为10位小数
     *
     * @param v1 被除数
     * @param v2 除数
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2) {
        return divide(v1, v2, DEFAULT_DIV_SCALE);
    }

    /**
     * 提供精确的除法运算
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 精度（保留小数位数）
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("精度不能小于0");
        }
        BigDecimal b1 = BigDecimal.valueOf(v1);
        BigDecimal b2 = BigDecimal.valueOf(v2);
        return b1.divide(b2, scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v     需要四舍五入的数字
     * @param scale 精度（保留小数位数）
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
        if (scale < 0) {
            throw new IllegalArgumentException("精度不能小于0");
        }
        BigDecimal b = BigDecimal.valueOf(v);
        return b.setScale(scale, RoundingMode.HALF_UP).doubleValue();
    }

    /**
     * 格式化数字显示
     *
     * @param number  数字
     * @param pattern 格式模式（如 "#,##0.00"）
     * @return 格式化后的字符串
     */
    public static String format(Number number, String pattern) {
        if (number == null) {
            return null;
        }
        DecimalFormat df = new DecimalFormat(pattern);
        return df.format(number);
    }

    /**
     * 格式化为货币显示
     *
     * @param number 数字
     * @return 格式化后的货币字符串
     */
    public static String formatCurrency(Number number) {
        if (number == null) {
            return null;
        }
        NumberFormat nf = NumberFormat.getCurrencyInstance(Locale.CHINA);
        return nf.format(number);
    }

    /**
     * 判断数字是否为正数
     *
     * @param number 数字
     * @return 如果为正数返回true，否则返回false
     */
    public static boolean isPositive(Number number) {
        if (number == null) {
            return false;
        }
        return number.doubleValue() > 0;
    }

    /**
     * 判断数字是否为负数
     *
     * @param number 数字
     * @return 如果为负数返回true，否则返回false
     */
    public static boolean isNegative(Number number) {
        if (number == null) {
            return false;
        }
        return number.doubleValue() < 0;
    }

    /**
     * 判断数字是否为零
     *
     * @param number 数字
     * @return 如果为零返回true，否则返回false
     */
    public static boolean isZero(Number number) {
        if (number == null) {
            return false;
        }
        return number.doubleValue() == 0;
    }

    /**
     * 比较两个数字的大小
     *
     * @param n1 第一个数字
     * @param n2 第二个数字
     * @return 如果n1>n2返回1，如果n1=n2返回0，如果n1<n2返回-1
     */
    public static int compare(Number n1, Number n2) {
        if (n1 == null && n2 == null) {
            return 0;
        }
        if (n1 == null) {
            return -1;
        }
        if (n2 == null) {
            return 1;
        }
        return Double.compare(n1.doubleValue(), n2.doubleValue());
    }

    /**
     * 获取两个数中的最大值
     *
     * @param n1 第一个数字
     * @param n2 第二个数字
     * @return 较大的数字
     */
    public static Number max(Number n1, Number n2) {
        return compare(n1, n2) >= 0 ? n1 : n2;
    }

    /**
     * 获取两个数中的最小值
     *
     * @param n1 第一个数字
     * @param n2 第二个数字
     * @return 较小的数字
     */
    public static Number min(Number n1, Number n2) {
        return compare(n1, n2) <= 0 ? n1 : n2;
    }
    
    /**
     * 对传入的数字进行倒序后输出字符串
     *
     * @param number 需要倒序的数字
     * @return 倒序后的字符串
     */
    public static String reverseNumber(Number number) {
        if (number == null) {
            return null;
        }
        String numStr = number.toString();
        StringBuilder sb = new StringBuilder();
        
        // 处理负数情况
        boolean isNegative = false;
        int startIndex = 0;
        if (numStr.charAt(0) == '-') {
            isNegative = true;
            startIndex = 1;
            sb.append('-');
        }
        
        // 倒序处理数字部分
        for (int i = numStr.length() - 1; i >= startIndex; i--) {
            sb.append(numStr.charAt(i));
        }
        
        return sb.toString();
    }
}